from statsmodels.compat.pandas import (
    QUARTER_END,
    assert_frame_equal,
    make_dataframe,
)

from datetime import datetime

import numpy as np
from numpy import array, column_stack
from numpy.testing import (
    assert_allclose,
    assert_almost_equal,
    assert_equal,
)
from pandas import DataFrame, concat, date_range
import pytest

from statsmodels.datasets import macrodata
from statsmodels.tsa.filters._utils import pandas_wrapper
from statsmodels.tsa.filters.bk_filter import bkfilter
from statsmodels.tsa.filters.cf_filter import cffilter
from statsmodels.tsa.filters.filtertools import (
    convolution_filter,
    recursive_filter,
)
from statsmodels.tsa.filters.hp_filter import hpfilter


def test_bking1d():
    # Test Baxter King band-pass filter. Results are taken from Stata
    bking_results = array(
        [
            7.320813,
            2.886914,
            -6.818976,
            -13.49436,
            -13.27936,
            -9.405913,
            -5.691091,
            -5.133076,
            -7.273468,
            -9.243364,
            -8.482916,
            -4.447764,
            2.406559,
            10.68433,
            19.46414,
            28.09749,
            34.11066,
            33.48468,
            24.64598,
            9.952399,
            -4.265528,
            -12.59471,
            -13.46714,
            -9.049501,
            -3.011248,
            0.5655082,
            2.897976,
            7.406077,
            14.67959,
            18.651,
            13.05891,
            -2.945415,
            -24.08659,
            -41.86147,
            -48.68383,
            -43.32689,
            -31.66654,
            -20.38356,
            -13.76411,
            -9.978693,
            -3.7704,
            10.27108,
            31.02847,
            51.87613,
            66.93117,
            73.51951,
            73.4053,
            69.17468,
            59.8543,
            38.23899,
            -0.2604809,
            -49.0107,
            -91.1128,
            -112.1574,
            -108.3227,
            -86.51453,
            -59.91258,
            -40.01185,
            -29.70265,
            -22.76396,
            -13.08037,
            1.913622,
            20.44045,
            37.32873,
            46.79802,
            51.95937,
            59.67393,
            70.50803,
            81.27311,
            83.53191,
            67.72536,
            33.78039,
            -6.509092,
            -37.31579,
            -46.05207,
            -29.81496,
            1.416417,
            28.31503,
            32.90134,
            8.949259,
            -35.41895,
            -84.65775,
            -124.4288,
            -144.6036,
            -140.2204,
            -109.2624,
            -53.6901,
            15.07415,
            74.44268,
            104.0403,
            101.0725,
            76.58291,
            49.27925,
            36.15751,
            36.48799,
            37.60897,
            27.75998,
            4.216643,
            -23.20579,
            -39.33292,
            -36.6134,
            -20.90161,
            -4.143123,
            5.48432,
            9.270075,
            13.69573,
            22.16675,
            33.01987,
            41.93186,
            47.12222,
            48.62164,
            47.30701,
            40.20537,
            22.37898,
            -7.133002,
            -43.3339,
            -78.51229,
            -101.3684,
            -105.2179,
            -90.97147,
            -68.30824,
            -48.10113,
            -35.60709,
            -31.15775,
            -31.82346,
            -32.49278,
            -28.22499,
            -14.42852,
            10.1827,
            36.64189,
            49.43468,
            38.75517,
            6.447761,
            -33.15883,
            -62.60446,
            -72.87829,
            -66.54629,
            -52.61205,
            -38.06676,
            -26.19963,
            -16.51492,
            -7.007577,
            0.6125674,
            7.866972,
            14.8123,
            22.52388,
            30.65265,
            39.47801,
            49.05027,
            59.02925,
            72.88999,
            95.08865,
            125.8983,
            154.4283,
            160.7638,
            130.6092,
            67.84406,
            -7.070272,
            -68.08128,
            -99.39944,
            -104.911,
            -100.2372,
            -98.11596,
            -104.2051,
            -114.0125,
            -113.3475,
            -92.98669,
            -51.91707,
            -0.7313812,
            43.22938,
            64.62762,
            64.07226,
            59.35707,
            67.06026,
            91.87247,
            124.4591,
            151.2402,
            163.0648,
            154.6432,
        ]
    )
    X = macrodata.load_pandas().data["realinv"].values
    Y = bkfilter(X, 6, 32, 12)
    assert_almost_equal(Y, bking_results, 4)


def test_bking2d():
    # Test Baxter-King band-pass filter with 2d input
    bking_results = array(
        [
            [7.320813, -0.0374475],
            [2.886914, -0.0430094],
            [-6.818976, -0.053456],
            [-13.49436, -0.0620739],
            [-13.27936, -0.0626929],
            [-9.405913, -0.0603022],
            [-5.691091, -0.0630016],
            [-5.133076, -0.0832268],
            [-7.273468, -0.1186448],
            [-9.243364, -0.1619868],
            [-8.482916, -0.2116604],
            [-4.447764, -0.2670747],
            [2.406559, -0.3209931],
            [10.68433, -0.3583075],
            [19.46414, -0.3626742],
            [28.09749, -0.3294618],
            [34.11066, -0.2773388],
            [33.48468, -0.2436127],
            [24.64598, -0.2605531],
            [9.952399, -0.3305166],
            [-4.265528, -0.4275561],
            [-12.59471, -0.5076068],
            [-13.46714, -0.537573],
            [-9.049501, -0.5205845],
            [-3.011248, -0.481673],
            [0.5655082, -0.4403994],
            [2.897976, -0.4039957],
            [7.406077, -0.3537394],
            [14.67959, -0.2687359],
            [18.651, -0.1459743],
            [13.05891, 0.0014926],
            [-2.945415, 0.1424277],
            [-24.08659, 0.2451936],
            [-41.86147, 0.288541],
            [-48.68383, 0.2727282],
            [-43.32689, 0.1959127],
            [-31.66654, 0.0644874],
            [-20.38356, -0.1158372],
            [-13.76411, -0.3518627],
            [-9.978693, -0.6557535],
            [-3.7704, -1.003754],
            [10.27108, -1.341632],
            [31.02847, -1.614486],
            [51.87613, -1.779089],
            [66.93117, -1.807459],
            [73.51951, -1.679688],
            [73.4053, -1.401012],
            [69.17468, -0.9954996],
            [59.8543, -0.511261],
            [38.23899, -0.0146745],
            [-0.2604809, 0.4261311],
            [-49.0107, 0.7452514],
            [-91.1128, 0.8879492],
            [-112.1574, 0.8282748],
            [-108.3227, 0.5851508],
            [-86.51453, 0.2351699],
            [-59.91258, -0.1208998],
            [-40.01185, -0.4297895],
            [-29.70265, -0.6821963],
            [-22.76396, -0.9234254],
            [-13.08037, -1.217539],
            [1.913622, -1.57367],
            [20.44045, -1.927008],
            [37.32873, -2.229565],
            [46.79802, -2.463154],
            [51.95937, -2.614697],
            [59.67393, -2.681357],
            [70.50803, -2.609654],
            [81.27311, -2.301618],
            [83.53191, -1.720974],
            [67.72536, -0.9837123],
            [33.78039, -0.2261613],
            [-6.509092, 0.4546985],
            [-37.31579, 1.005751],
            [-46.05207, 1.457224],
            [-29.81496, 1.870815],
            [1.416417, 2.263313],
            [28.31503, 2.599906],
            [32.90134, 2.812282],
            [8.949259, 2.83358],
            [-35.41895, 2.632667],
            [-84.65775, 2.201077],
            [-124.4288, 1.598951],
            [-144.6036, 0.9504762],
            [-140.2204, 0.4187932],
            [-109.2624, 0.1646726],
            [-53.6901, 0.2034265],
            [15.07415, 0.398165],
            [74.44268, 0.5427476],
            [104.0403, 0.5454975],
            [101.0725, 0.4723354],
            [76.58291, 0.4626823],
            [49.27925, 0.5840143],
            [36.15751, 0.7187981],
            [36.48799, 0.6058422],
            [37.60897, 0.1221227],
            [27.75998, -0.5891272],
            [4.216643, -1.249841],
            [-23.20579, -1.594972],
            [-39.33292, -1.545968],
            [-36.6134, -1.275494],
            [-20.90161, -1.035783],
            [-4.143123, -0.9971732],
            [5.48432, -1.154264],
            [9.270075, -1.29987],
            [13.69573, -1.240559],
            [22.16675, -0.9662656],
            [33.01987, -0.6420301],
            [41.93186, -0.4698712],
            [47.12222, -0.4527797],
            [48.62164, -0.4407153],
            [47.30701, -0.2416076],
            [40.20537, 0.2317583],
            [22.37898, 0.8710276],
            [-7.133002, 1.426177],
            [-43.3339, 1.652785],
            [-78.51229, 1.488021],
            [-101.3684, 1.072096],
            [-105.2179, 0.6496446],
            [-90.97147, 0.4193682],
            [-68.30824, 0.41847],
            [-48.10113, 0.5253419],
            [-35.60709, 0.595076],
            [-31.15775, 0.5509905],
            [-31.82346, 0.3755519],
            [-32.49278, 0.1297979],
            [-28.22499, -0.0916165],
            [-14.42852, -0.2531037],
            [10.1827, -0.3220784],
            [36.64189, -0.2660561],
            [49.43468, -0.1358522],
            [38.75517, -0.0279508],
            [6.447761, 0.0168735],
            [-33.15883, 0.0315687],
            [-62.60446, 0.0819507],
            [-72.87829, 0.2274033],
            [-66.54629, 0.4641401],
            [-52.61205, 0.7211093],
            [-38.06676, 0.907773],
            [-26.19963, 0.9387103],
            [-16.51492, 0.7940786],
            [-7.007577, 0.5026631],
            [0.6125674, 0.1224996],
            [7.866972, -0.2714422],
            [14.8123, -0.6273921],
            [22.52388, -0.9124271],
            [30.65265, -1.108861],
            [39.47801, -1.199206],
            [49.05027, -1.19908],
            [59.02925, -1.139046],
            [72.88999, -0.9775021],
            [95.08865, -0.6592603],
            [125.8983, -0.1609712],
            [154.4283, 0.4796201],
            [160.7638, 1.100565],
            [130.6092, 1.447148],
            [67.84406, 1.359608],
            [-7.070272, 0.8931825],
            [-68.08128, 0.2619787],
            [-99.39944, -0.252208],
            [-104.911, -0.4703874],
            [-100.2372, -0.4430657],
            [-98.11596, -0.390683],
            [-104.2051, -0.5647846],
            [-114.0125, -0.9397582],
            [-113.3475, -1.341633],
            [-92.98669, -1.567337],
            [-51.91707, -1.504943],
            [-0.7313812, -1.30576],
            [43.22938, -1.17151],
            [64.62762, -1.136151],
            [64.07226, -1.050555],
            [59.35707, -0.7308369],
            [67.06026, -0.1766731],
            [91.87247, 0.3898467],
            [124.4591, 0.8135461],
            [151.2402, 0.9644226],
            [163.0648, 0.6865934],
            [154.6432, 0.0115685],
        ]
    )

    mdata = macrodata.load_pandas()
    X = mdata.data[["realinv", "cpi"]].values.astype(float)
    Y = bkfilter(X, 6, 32, 12)
    assert_almost_equal(Y, bking_results, 4)


def test_hpfilter():
    # Test Hodrick-Prescott Filter. Results taken from Stata.
    hpfilt_res = array(
        [
            [3.951191484487844718e01, 2.670837085155121713e03],
            [8.008853245681075350e01, 2.698712467543189177e03],
            [4.887545512195401898e01, 2.726612544878045810e03],
            [3.059193256079834100e01, 2.754612067439201837e03],
            [6.488266733421960453e01, 2.782816332665780465e03],
            [2.304024204546703913e01, 2.811349757954532834e03],
            [-1.355312369487364776e00, 2.840377312369487299e03],
            [-6.746236512580753697e01, 2.870078365125807522e03],
            [-8.136743836853429457e01, 2.900631438368534418e03],
            [-6.016789026443257171e01, 2.932172890264432681e03],
            [-4.636922433138215638e01, 2.964788224331382025e03],
            [-2.069533915570400495e01, 2.998525339155703932e03],
            [-2.162152558595607843e00, 3.033403152558595593e03],
            [-4.718647774311648391e00, 3.069427647774311481e03],
            [-1.355645669169007306e01, 3.106603456691690099e03],
            [-4.436926204475639679e01, 3.144932262044756499e03],
            [-4.332027378211660107e01, 3.184407273782116590e03],
            [-4.454697106352068658e01, 3.224993971063520803e03],
            [-2.629875787765286077e01, 3.266630757877652741e03],
            [-4.426119635629265758e01, 3.309228196356292756e03],
            [-1.443441190762496262e01, 3.352680411907625057e03],
            [-2.026686669186437939e01, 3.396853866691864368e03],
            [-1.913700136208899494e01, 3.441606001362089046e03],
            [-5.482458977940950717e01, 3.486781589779409387e03],
            [-1.596244517937793717e01, 3.532213445179378141e03],
            [-1.374011542874541192e01, 3.577700115428745448e03],
            [1.325482813403914406e01, 3.623030171865960710e03],
            [5.603040174253828809e01, 3.667983598257461836e03],
            [1.030743373627105939e02, 3.712348662637289181e03],
            [7.217534795943993231e01, 3.755948652040559864e03],
            [5.462972503693208637e01, 3.798671274963067845e03],
            [4.407065050666142270e01, 3.840449349493338559e03],
            [3.749016270204992907e01, 3.881249837297949853e03],
            [-1.511244199923112319e00, 3.921067244199923152e03],
            [-9.093507374079763395e00, 3.959919507374079785e03],
            [-1.685361946760258434e01, 3.997823619467602384e03],
            [2.822211031434289907e01, 4.034790889685657021e03],
            [6.117590627896424849e01, 4.070822093721035344e03],
            [5.433135391434370831e01, 4.105935646085656117e03],
            [3.810480376716623141e01, 4.140188196232833434e03],
            [7.042964928802848590e01, 4.173670350711971878e03],
            [4.996346842507591646e01, 4.206496531574924120e03],
            [4.455282059571254649e01, 4.238825179404287155e03],
            [-7.584961950576143863e00, 4.270845961950576566e03],
            [-4.620339247697120300e01, 4.302776392476971523e03],
            [-7.054024364552969928e01, 4.334829243645529459e03],
            [-6.492941099801464588e01, 4.367188410998014660e03],
            [-1.433567024239555394e02, 4.399993702423955256e03],
            [-5.932834493089012540e01, 4.433344344930889747e03],
            [-6.842096758743628016e01, 4.467249967587436004e03],
            [-6.774011924654860195e01, 4.501683119246548813e03],
            [-9.030958565658056614e01, 4.536573585656580690e03],
            [-4.603981499136807543e01, 4.571808814991368308e03],
            [2.588118806672991923e01, 4.607219811933269739e03],
            [3.489419371912299539e01, 4.642608806280876706e03],
            [7.675179642495095322e01, 4.677794203575049323e03],
            [1.635497817724171910e02, 4.712616218227582976e03],
            [1.856079654765617306e02, 4.746963034523438182e03],
            [1.254269446392718237e02, 4.780825055360728584e03],
            [1.387413113837174024e02, 4.814308688616282780e03],
            [6.201826599282230745e01, 4.847598734007177882e03],
            [4.122129542972197669e01, 4.880966704570278125e03],
            [-4.120287475842360436e01, 4.914722874758424041e03],
            [-9.486328233441963675e01, 4.949203282334419782e03],
            [-1.894232132641573116e02, 4.984718213264157384e03],
            [-1.895766639620087517e02, 5.021518663962008759e03],
            [-1.464092413342650616e02, 5.059737241334265491e03],
            [-1.218770668721217589e02, 5.099388066872122181e03],
            [-4.973075629078175552e01, 5.140393756290781312e03],
            [-5.365375213897277717e01, 5.182600752138972894e03],
            [-7.175241524251214287e01, 5.225824415242512259e03],
            [-7.834757283225462743e01, 5.269846572832254424e03],
            [-6.264220687943907251e01, 5.314404206879438789e03],
            [-3.054332122210325906e00, 5.359185332122210639e03],
            [4.808218808024685131e01, 5.403838811919753425e03],
            [2.781399326736391231e00, 5.448011600673263274e03],
            [-2.197570415173231595e01, 5.491380704151732061e03],
            [1.509441335012807031e02, 5.533624866498719712e03],
            [1.658909029574851957e02, 5.574409097042514986e03],
            [2.027292548049981633e02, 5.613492745195001589e03],
            [1.752101578176061594e02, 5.650738842182393455e03],
            [1.452808749847536092e02, 5.686137125015246056e03],
            [1.535481629475025329e02, 5.719786837052497503e03],
            [1.376169777998875361e02, 5.751878022200112355e03],
            [1.257703080340770612e02, 5.782696691965922582e03],
            [-2.524186846895645431e01, 5.812614868468956047e03],
            [-6.546618027042404719e01, 5.842083180270424236e03],
            [1.192352023580315290e01, 5.871536479764196883e03],
            [1.043482970188742911e02, 5.901368702981125352e03],
            [2.581376184768396342e01, 5.931981238152316109e03],
            [6.634330880534071184e01, 5.963840691194659485e03],
            [-4.236780162594641297e01, 5.997429801625946311e03],
            [-1.759397735321817891e02, 6.033272773532181418e03],
            [-1.827933311233055065e02, 6.071867331123305121e03],
            [-2.472312362505917918e02, 6.113601236250591683e03],
            [-2.877470049336488955e02, 6.158748004933649099e03],
            [-2.634066336693540507e02, 6.207426633669354487e03],
            [-1.819572770763625158e02, 6.259576277076362203e03],
            [-1.175034606274621183e02, 6.314971460627461965e03],
            [-4.769898649718379602e01, 6.373272986497183410e03],
            [1.419578280287896632e01, 6.434068217197121157e03],
            [6.267929662760798237e01, 6.496914703372392069e03],
            [6.196413196753746888e01, 6.561378868032462378e03],
            [5.019769125317907310e01, 6.627066308746821051e03],
            [4.665364933213822951e01, 6.693621350667861407e03],
            [3.662430749527266016e01, 6.760719692504727391e03],
            [7.545680850246480986e01, 6.828066191497535328e03],
            [6.052940492147536133e01, 6.895388595078524304e03],
            [6.029518881462354329e01, 6.962461811185376064e03],
            [2.187042136652689805e01, 7.029098578633473153e03],
            [2.380067926824722235e01, 7.095149320731752596e03],
            [-7.119129802169481991e00, 7.160478129802169860e03],
            [-3.194497359120850888e01, 7.224963973591208742e03],
            [-1.897137038934124575e01, 7.288481370389341464e03],
            [-1.832687287845146784e01, 7.350884872878451461e03],
            [4.600482336597542599e01, 7.412017176634024509e03],
            [2.489047706403016491e01, 7.471709522935970199e03],
            [6.305909392127250612e01, 7.529821906078727807e03],
            [4.585212309498183458e01, 7.586229876905018500e03],
            [9.314260180878318351e01, 7.640848398191216802e03],
            [1.129819097095369216e02, 7.693621090290463144e03],
            [1.204662123176703972e02, 7.744549787682329224e03],
            [1.336860614601246198e02, 7.793706938539875409e03],
            [1.034567175813735957e02, 7.841240282418626521e03],
            [1.403118873372050075e02, 7.887381112662795204e03],
            [1.271726169351004501e02, 7.932425383064899506e03],
            [8.271925765282139764e01, 7.976756742347178260e03],
            [-3.197432211752584408e01, 8.020838322117525422e03],
            [-1.150209535194062482e02, 8.065184953519406008e03],
            [-1.064694837456772802e02, 8.110291483745677397e03],
            [-1.190428718925368230e02, 8.156580871892536379e03],
            [-1.353635336292991269e02, 8.204409533629299403e03],
            [-9.644348283027102298e01, 8.254059482830271008e03],
            [-6.143413116116607853e01, 8.305728131161165948e03],
            [-3.019161311097923317e01, 8.359552613110980019e03],
            [1.384333163552582846e00, 8.415631666836447039e03],
            [-4.156016073666614830e01, 8.474045160736666730e03],
            [-4.843882841860977351e01, 8.534873828418609264e03],
            [-6.706442838867042155e01, 8.598172428388670596e03],
            [-2.019644488579979225e01, 8.663965444885800025e03],
            [-4.316446881084630149e00, 8.732235446881084499e03],
            [4.435061943264736328e01, 8.802952380567352520e03],
            [2.820550564155564643e01, 8.876083494358445023e03],
            [5.155624419490777655e01, 8.951623755805092514e03],
            [-4.318760899315748247e00, 9.029585760899315574e03],
            [-6.534632828542271454e01, 9.110014328285422380e03],
            [-7.226757738268497633e01, 9.192951577382684263e03],
            [-9.412378615444868046e01, 9.278398786154448317e03],
            [-1.191240653288368776e02, 9.366312065328836979e03],
            [-4.953669826751865912e01, 9.456588698267518339e03],
            [-6.017251579067487910e01, 9.549051515790675694e03],
            [-5.103438828313483100e01, 9.643492388283135369e03],
            [-7.343057830678117170e01, 9.739665578306781754e03],
            [-2.774245193054957781e01, 9.837293451930549054e03],
            [-3.380481112519191811e00, 9.936052481112519672e03],
            [-2.672779877794346248e01, 1.003560179877794326e04],
            [-3.217342505148371856e01, 1.013559842505148299e04],
            [-4.140567518359966925e01, 1.023568267518359971e04],
            [-6.687756033938057953e00, 1.033547475603393832e04],
            [7.300600408459467872e01, 1.043456899591540605e04],
            [6.862345670680042531e01, 1.053255554329319966e04],
            [5.497882461487461114e01, 1.062907017538512628e04],
            [9.612244093055960548e01, 1.072379155906944106e04],
            [1.978212770103891671e02, 1.081643272298961165e04],
            [1.362772276848754700e02, 1.090676677231512440e04],
            [2.637635494867263333e02, 1.099469045051327339e04],
            [1.876813256815166824e02, 1.108018567431848351e04],
            [1.711447873158413131e02, 1.116339921268415856e04],
            [5.257586460826678376e01, 1.124459513539173349e04],
            [4.710652228531762375e01, 1.132414447771468258e04],
            [-6.237613484241046535e01, 1.140245113484241119e04],
            [-9.982044354035315337e01, 1.147994844354035376e04],
            [-7.916275548997509759e01, 1.155703075548997549e04],
            [-9.526003459472303803e01, 1.163403003459472347e04],
            [-1.147987680369169539e02, 1.171122876803691724e04],
            [-1.900259054765901965e02, 1.178884990547659072e04],
            [-2.212256473439556430e02, 1.186704464734395515e04],
            [-2.071394278781845060e02, 1.194584542787818464e04],
            [-8.968541528904825100e01, 1.202514641528904758e04],
            [-6.189531564415665343e01, 1.210471231564415575e04],
            [-5.662878162551714922e01, 1.218425178162551674e04],
            [-4.961678134413705266e01, 1.226343478134413635e04],
            [-3.836288992144181975e01, 1.234189588992144127e04],
            [-8.956671991456460091e00, 1.241923867199145570e04],
            [3.907028461866866564e01, 1.249504271538133071e04],
            [1.865299000184495526e01, 1.256888200999815490e04],
            [4.279803532226833340e01, 1.264035496467773191e04],
            [3.962735362631610769e01, 1.270907164637368442e04],
            [1.412691291877854383e02, 1.277466887081221466e04],
            [1.256537791844366438e02, 1.283680822081556289e04],
            [7.067642758858892194e01, 1.289523957241141034e04],
            [1.108876647603192396e02, 1.294979133523968085e04],
            [9.956490829291760747e01, 1.300033609170708223e04],
            [1.571612709880937473e02, 1.304681572901190702e04],
            [2.318746375812715996e02, 1.308923436241872878e04],
            [2.635546670125277160e02, 1.312769433298747208e04],
            [2.044220965739259555e02, 1.316244290342607383e04],
            [2.213739418903714977e02, 1.319389205810962812e04],
            [1.020184547767112235e02, 1.322258154522328914e04],
            [-1.072694716663390864e02, 1.324918947166633916e04],
            [-3.490477058718843182e02, 1.327445770587188417e04],
            [-3.975570728533530200e02, 1.329906107285335383e04],
            [-3.331152428080622485e02, 1.332345624280806260e04],
        ]
    )
    dta = macrodata.load_pandas().data["realgdp"].values
    res = column_stack(hpfilter(dta, 1600))
    assert_almost_equal(res, hpfilt_res, 6)


def test_cfitz_filter():
    # Test Christiano-Fitzgerald Filter. Results taken from R.
    # NOTE: The Stata mata code and the matlab code it's based on are wrong.
    cfilt_res = array(
        [
            [0.712599537179426, 0.439563468233128],
            [1.06824041304411, 0.352886666575907],
            [1.19422467791128, 0.257297004260607],
            [0.970845473140327, 0.114504692143872],
            [0.467026976628563, -0.070734782329146],
            [-0.089153511514031, -0.238609685132605],
            [-0.452339254128573, -0.32376584042956],
            [-0.513231214461187, -0.314288554228112],
            [-0.352372578720063, -0.258815055101336],
            [-0.160282602521333, -0.215076844089567],
            [-0.0918782593827686, -0.194120745417214],
            [-0.168083823205437, -0.158327420072693],
            [-0.291595204965808, -0.0742727139742986],
            [-0.348638756841307, 0.037008291163602],
            [-0.304328040874631, 0.108196527328748],
            [-0.215933150969686, 0.0869231107437175],
            [-0.165632621390694, -0.0130556619786275],
            [-0.182326839507151, -0.126570926191824],
            [-0.223737786804725, -0.205535321806185],
            [-0.228939291453403, -0.269110078201836],
            [-0.185518327227038, -0.375976507132174],
            [-0.143900152461529, -0.53760115656157],
            [-0.162749541550174, -0.660065018626038],
            [-0.236263634756884, -0.588542352053736],
            [-0.275785854309211, -0.236867929421996],
            [-0.173666515108109, 0.303436335579219],
            [0.0963135720251639, 0.779772338801993],
            [0.427070069032285, 0.929108075350647],
            [0.629034743259998, 0.658330841002647],
            [0.557941248993624, 0.118500049361018],
            [0.227866624051603, -0.385048321099911],
            [-0.179878859883227, -0.582223992561493],
            [-0.428263000051965, -0.394053702908091],
            [-0.381640684645912, 0.0445437406977307],
            [-0.0942745548364887, 0.493997792757968],
            [0.238132391504895, 0.764519811304315],
            [0.431293754256291, 0.814755206427316],
            [0.455010435813661, 0.745567043101108],
            [0.452800768971269, 0.709401694610443],
            [0.615754619329312, 0.798293251119636],
            [1.00256335412457, 0.975856845059388],
            [1.44841039351691, 1.09097252730799],
            [1.64651971120370, 0.967823457118036],
            [1.35534532901802, 0.522397724737059],
            [0.580492790312048, -0.16941343361609],
            [-0.410746188031773, -0.90760401289056],
            [-1.26148406066881, -1.49592867122591],
            [-1.75784179124566, -1.87404167409849],
            [-1.94478553960064, -2.14586210891112],
            [-2.03751202708559, -2.465855239868],
            [-2.20376059354166, -2.86294187189049],
            [-2.39722338315852, -3.15004697654831],
            [-2.38032366161537, -3.01390466643222],
            [-1.91798022532025, -2.23395210271226],
            [-0.982318490353716, -0.861346053067472],
            [0.199047030343412, 0.790266582335616],
            [1.28582776574786, 2.33731327460104],
            [2.03565905376430, 3.54085486821911],
            [2.41201557412526, 4.36519456268955],
            [2.52011070482927, 4.84810517685452],
            [2.45618479815452, 4.92906708807477],
            [2.22272146945388, 4.42591058990048],
            [1.78307567169034, 3.20962906108388],
            [1.18234431860844, 1.42568060336985],
            [0.590069172333348, -0.461896808688991],
            [0.19662302949837, -1.89020992539465],
            [0.048307034171166, -2.53490571941987],
            [-0.0141956981899000, -2.50020338531674],
            [-0.230505187108187, -2.20625973569823],
            [-0.700947410386801, -2.06643697511048],
            [-1.27085123163060, -2.21536883679783],
            [-1.64082547897928, -2.49016921117735],
            [-1.62286182971254, -2.63948740221362],
            [-1.31609762181362, -2.54685250637904],
            [-1.03085567704873, -2.27157435428923],
            [-1.01100120380112, -1.90404507430561],
            [-1.19823958399826, -1.4123209792214],
            [-1.26398933608383, -0.654000086153317],
            [-0.904710628949692, 0.447960016248203],
            [-0.151340093679588, 1.73970411237156],
            [0.592926881165989, 2.85741581650685],
            [0.851660587507523, 3.4410446351716],
            [0.480324393352127, 3.36870271362297],
            [-0.165153230782417, 2.82003806696544],
            [-0.459235919375844, 2.12858991660866],
            [0.0271158842479935, 1.55840980891556],
            [1.18759188180671, 1.17980298478623],
            [2.43238266962309, 0.904011534980672],
            [3.08277213720132, 0.595286911949837],
            [2.79953663720953, 0.148014782859571],
            [1.73694442845833, -0.496297332023011],
            [0.357638079951977, -1.33108149877570],
            [-0.891418825216945, -2.22650083183366],
            [-1.77646467793627, -2.89359299718574],
            [-2.24614790863088, -2.97921619243347],
            [-2.29048879096607, -2.30003092779280],
            [-1.87929656465888, -1.05298381273274],
            [-1.04510101454788, 0.215837488618531],
            [0.00413338508394524, 0.937866257924888],
            [0.906870625251025, 0.92664365343019],
            [1.33869057593416, 0.518564571494679],
            [1.22659678454440, 0.288096869652890],
            [0.79380139656044, 0.541053084632774],
            [0.38029431865832, 1.01905199983437],
            [0.183929413600038, 1.10529586616777],
            [0.140045425897033, 0.393618564826736],
            [0.0337313182352219, -0.86431819007665],
            [-0.269208622829813, -1.85638085246792],
            [-0.687276639992166, -1.82275359004533],
            [-1.00161592325614, -0.692695765071617],
            [-1.06320089194036, 0.803577361347341],
            [-0.927152307196776, 1.67366338751788],
            [-0.786802101366614, 1.42564362251793],
            [-0.772970884572502, 0.426446388877964],
            [-0.81275662801789, -0.437721213831647],
            [-0.686831250382476, -0.504255468075149],
            [-0.237936463020255, 0.148656301898438],
            [0.459631879129522, 0.832925905720478],
            [1.12717379822508, 0.889455302576383],
            [1.48640453200855, 0.268042676202216],
            [1.46515245776211, -0.446505038539178],
            [1.22993484959115, -0.563868578181134],
            [1.0272100765927, 0.0996849952196907],
            [0.979191212438404, 1.05053652824665],
            [1.00733490030391, 1.51658415000556],
            [0.932192535457706, 1.06262774912638],
            [0.643374300839414, -0.0865180803476065],
            [0.186885168954461, -1.24799408923277],
            [-0.290842337365465, -1.80035611156538],
            [-0.669446735516495, -1.58847333561510],
            [-0.928915624595538, -0.932116966867929],
            [-1.11758635926997, -0.307879396807850],
            [-1.26832454569756, -0.00856199983957032],
            [-1.35755577149251, -0.0303537516690989],
            [-1.34244112665546, -0.196807620887435],
            [-1.22227976023299, -0.342062643495923],
            [-1.04601473486818, -0.390474392372016],
            [-0.85158508717846, -0.322164402093596],
            [-0.605033439160543, -0.126930141915954],
            [-0.218304303942818, 0.179551077808122],
            [0.352173017779006, 0.512327303000081],
            [1.01389600097229, 0.733397490572755],
            [1.55149778750607, 0.748740387440165],
            [1.75499674757591, 0.601759717901009],
            [1.56636057468633, 0.457705308377562],
            [1.12239792537274, 0.470849913286519],
            [0.655802600286141, 0.646142040378738],
            [0.335285115340180, 0.824103600255079],
            [0.173454596506888, 0.808068498175582],
            [0.0666753011315252, 0.521488214487996],
            [-0.0842367474816212, 0.0583493276173476],
            [-0.285604762631464, -0.405958418332253],
            [-0.465735422869919, -0.747800086512926],
            [-0.563586691231348, -0.94982272350799],
            [-0.598110322024572, -1.04736894794361],
            [-0.65216025756061, -1.04858365218822],
            [-0.789663117801624, -0.924145633093637],
            [-0.984704045337959, -0.670740724179446],
            [-1.12449565589348, -0.359476803003931],
            [-1.07878318723543, -0.092290938944355],
            [-0.775555435407062, 0.102132527529259],
            [-0.231610677329856, 0.314409560305622],
            [0.463192794235131, 0.663523546243286],
            [1.17416973448423, 1.13156902460931],
            [1.74112278814906, 1.48967153067024],
            [2.00320855757084, 1.42571085941843],
            [1.8529912317336, 0.802460519079555],
            [1.30747261947211, -0.169219078629572],
            [0.540237070403222, -1.01621539672694],
            [-0.177136817092375, -1.3130784867977],
            [-0.611981468823591, -0.982477824460773],
            [-0.700240028737747, -0.344919609255406],
            [-0.572396497740112, 0.125083535035390],
            [-0.450934466600975, 0.142553112732280],
            [-0.494020014254326, -0.211429053871656],
            [-0.701707589094918, -0.599602868825992],
            [-0.94721339346157, -0.710669870591623],
            [-1.09297139748946, -0.47846194092245],
            [-1.08850658866583, -0.082258450179988],
            [-0.976082880696692, 0.235758921309309],
            [-0.81885695346771, 0.365298185204303],
            [-0.63165529525553, 0.384725179378064],
            [-0.37983149226421, 0.460240196164378],
            [-0.0375551354277652, 0.68580913832794],
            [0.361996927427804, 0.984470835955107],
            [0.739920615366072, 1.13195975020298],
            [1.03583478061534, 0.88812510421667],
            [1.25614938962160, 0.172561520611839],
            [1.45295030231799, -0.804979390544485],
            [1.64887158748426, -1.55662011197859],
            [1.78022721495313, -1.52921975346218],
            [1.71945683859668, -0.462240366424548],
            [1.36728880239190, 1.31213774341268],
            [0.740173894315912, 2.88362740582926],
            [-0.0205364331835904, 3.20319080963167],
            [-0.725643970956428, 1.75222466531151],
            [-1.23900506689782, -0.998432917440275],
            [-1.52651897508678, -3.72752870885448],
            [-1.62857516631435, -5.00551707196292],
            [-1.59657420180451, -4.18499132634584],
            [-1.45489013276495, -1.81759097305637],
            [-1.21309542313047, 0.722029457352468],
        ]
    )
    dta = macrodata.load_pandas().data[["tbilrate", "infl"]].values[1:]
    cyc, trend = cffilter(dta)
    assert_almost_equal(cyc, cfilt_res, 8)
    # do 1d
    cyc, trend = cffilter(dta[:, 1])
    assert_almost_equal(cyc, cfilt_res[:, 1], 8)


def test_bking_pandas():
    # 1d
    dta = macrodata.load_pandas().data
    index = date_range(start="1959-01-01", end="2009-10-01", freq=QUARTER_END)
    dta.index = index
    filtered = bkfilter(dta["infl"])
    nd_filtered = bkfilter(dta["infl"].values)
    assert_equal(filtered.values, nd_filtered)
    assert_equal(filtered.index[0], datetime(1962, 3, 31))
    assert_equal(filtered.index[-1], datetime(2006, 9, 30))
    assert_equal(filtered.name, "infl_cycle")

    # 2d
    filtered = bkfilter(dta[["infl", "unemp"]])
    nd_filtered = bkfilter(dta[["infl", "unemp"]].values)
    assert_equal(filtered.values, nd_filtered)
    assert_equal(filtered.index[0], datetime(1962, 3, 31))
    assert_equal(filtered.index[-1], datetime(2006, 9, 30))
    assert_equal(np.asarray(filtered.columns.values), ["infl_cycle", "unemp_cycle"])


def test_cfitz_pandas():
    # 1d
    dta = macrodata.load_pandas().data
    index = date_range(start="1959-01-01", end="2009-10-01", freq=QUARTER_END)
    dta.index = index
    cycle, trend = cffilter(dta["infl"])
    ndcycle, ndtrend = cffilter(dta["infl"].values)
    assert_allclose(cycle.values, ndcycle, rtol=1e-14)
    assert_equal(cycle.index[0], datetime(1959, 3, 31))
    assert_equal(cycle.index[-1], datetime(2009, 9, 30))
    assert_equal(cycle.name, "infl_cycle")

    # 2d
    cycle, trend = cffilter(dta[["infl", "unemp"]])
    ndcycle, ndtrend = cffilter(dta[["infl", "unemp"]].values)
    assert_allclose(cycle.values, ndcycle, rtol=1e-14)
    assert_equal(cycle.index[0], datetime(1959, 3, 31))
    assert_equal(cycle.index[-1], datetime(2009, 9, 30))
    assert_equal(np.asarray(cycle.columns.values), ["infl_cycle", "unemp_cycle"])


def test_hpfilter_pandas():
    dta = macrodata.load_pandas().data
    index = date_range(start="1959-01-01", end="2009-10-01", freq=QUARTER_END)
    dta.index = index
    cycle, trend = hpfilter(dta["realgdp"])
    ndcycle, ndtrend = hpfilter(dta["realgdp"].values)
    assert_equal(cycle.values, ndcycle)
    assert_equal(cycle.index[0], datetime(1959, 3, 31))
    assert_equal(cycle.index[-1], datetime(2009, 9, 30))
    assert_equal(cycle.name, "realgdp_cycle")


class TestFilters:
    @classmethod
    def setup_class(cls):
        # even
        data = [
            -50,
            175,
            149,
            214,
            247,
            237,
            225,
            329,
            729,
            809,
            530,
            489,
            540,
            457,
            195,
            176,
            337,
            239,
            128,
            102,
            232,
            429,
            3,
            98,
            43,
            -141,
            -77,
            -13,
            125,
            361,
            -45,
            184,
        ]
        cls.data = DataFrame(
            data, date_range(start="1/1/1951", periods=len(data), freq=QUARTER_END)
        )
        data[9] = np.nan
        cls.datana = DataFrame(
            data, date_range(start="1/1/1951", periods=len(data), freq=QUARTER_END)
        )
        from .results import filter_results

        cls.expected = filter_results

    def test_convolution(self):
        x = self.data.values.squeeze()
        res = convolution_filter(x, [0.75, 0.25])
        expected = self.expected.conv2
        np.testing.assert_almost_equal(res, expected)

        res = convolution_filter(x, [0.75, 0.25], nsides=1)
        expected = self.expected.conv1
        np.testing.assert_almost_equal(res, expected)

        x = self.datana.values.squeeze()
        res = convolution_filter(x, [0.75, 0.25])
        expected = self.expected.conv2_na
        np.testing.assert_almost_equal(res, expected)

        res = convolution_filter(x, [0.75, 0.25], nsides=1)
        expected = self.expected.conv1_na
        np.testing.assert_almost_equal(res, expected)

    def test_convolution2d(self):
        x = self.data.values
        res = convolution_filter(x, [[0.75], [0.25]])
        expected = self.expected.conv2
        np.testing.assert_almost_equal(res, expected[:, None])
        res = convolution_filter(np.c_[x, x], [[0.75, 0.75], [0.25, 0.25]])
        np.testing.assert_almost_equal(res, np.c_[expected, expected])

        res = convolution_filter(x, [[0.75], [0.25]], nsides=1)
        expected = self.expected.conv1
        np.testing.assert_almost_equal(res, expected[:, None])

        x = self.datana.values
        res = convolution_filter(x, [[0.75], [0.25]])
        expected = self.expected.conv2_na
        np.testing.assert_almost_equal(res, expected[:, None])

        res = convolution_filter(x, [[0.75], [0.25]], nsides=1)
        expected = self.expected.conv1_na
        np.testing.assert_almost_equal(res, expected[:, None])

    def test_recursive(self):
        x = self.data.values.squeeze()
        res = recursive_filter(x, [0.75, 0.25])
        expected = self.expected.recurse
        np.testing.assert_almost_equal(res, expected)

        res = recursive_filter(x, [0.75, 0.25], init=[150, 100])
        expected = self.expected.recurse_init
        np.testing.assert_almost_equal(res, expected)

        x = self.datana.values.squeeze()
        res = recursive_filter(x, [0.75, 0.25])
        expected = self.expected.recurse_na
        np.testing.assert_almost_equal(res, expected)

        res = recursive_filter(x, [0.75, 0.25], init=[150, 100])
        expected = self.expected.recurse_init_na
        np.testing.assert_almost_equal(res, expected)

        with pytest.raises(ValueError):
            recursive_filter(x, [0.75, 0.25, 0.5], [150, 100])

    def test_pandas(self):
        start = datetime(1951, 3, 31)
        end = datetime(1958, 12, 31)
        x = self.data[0]
        res = convolution_filter(x, [0.75, 0.25])
        assert (res.index[0] == start)
        assert (res.index[-1] == end)

        res = convolution_filter(x, [0.75, 0.25], nsides=1)
        assert (res.index[0] == start)
        # with no nan-padding q1 if not
        assert (res.index[-1] == end)

        res = recursive_filter(x, [0.75, 0.25])
        assert (res.index[0] == start)
        assert (res.index[-1] == end)

        x = self.datana
        res = recursive_filter(x, [0.75, 0.25])
        assert (res.index[0] == start)
        assert (res.index[-1] == end)

    def test_pandas2d(self):
        start = datetime(1951, 3, 31)
        end = datetime(1958, 12, 31)
        x = concat((self.data[0], self.data[0]), axis=1)
        res = convolution_filter(x, [[0.75, 0.75], [0.25, 0.25]])
        assert (res.index[0] == start)
        assert (res.index[-1] == end)

    def test_odd_length_filter(self):
        start = datetime(1951, 3, 31)
        end = datetime(1958, 12, 31)
        x = self.data[0]
        res = convolution_filter(x, [0.75, 0.5, 0.3, 0.2, 0.1])
        expected = self.expected.conv2_odd
        np.testing.assert_almost_equal(res.values.squeeze(), expected)
        assert res.index[0] == start
        assert res.index[-1] == end

        res = convolution_filter(x, [0.75, 0.5, 0.3, 0.2, 0.1], nsides=1)
        expected = self.expected.conv1_odd
        np.testing.assert_almost_equal(res.values.squeeze(), expected)
        assert res.index[0] == start
        assert res.index[-1] == end
        # with no NAs

        # not a stable filter
        res = recursive_filter(
            x, [0.75, 0.5, 0.3, 0.2, 0.1], init=[150, 100, 125, 135, 145]
        )
        expected = self.expected.recurse_odd
        # only have 12 characters in R and this blows up and gets big
        np.testing.assert_almost_equal(res.values.squeeze(), expected, 4)
        assert res.index[0] == start
        assert res.index[-1] == end


def dummy_func(x):
    return x


def dummy_func_array(x):
    return x.values


def dummy_func_pandas_columns(x):
    return x.values


def dummy_func_pandas_series(x):
    return x["A"]


def test_pandas_freq_decorator():
    x = make_dataframe()
    # in x, get a function back that returns an x with the same columns
    func = pandas_wrapper(dummy_func)

    np.testing.assert_equal(func(x.values), x)

    func = pandas_wrapper(dummy_func_array)
    assert_frame_equal(func(x), x)

    expected = x.rename(columns=dict(zip("ABCD", "EFGH")))
    func = pandas_wrapper(dummy_func_array, names=list("EFGH"))
    assert_frame_equal(func(x), expected)
